package org.kiwi.preheat;

import org.kiwi.preheat.spi.PreheatProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.SmartLifecycle;

import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;

/**
 * 预热监听器
 *
 * @email jack.liu.19910921@gmail.com
 * Created by jack on 16/12/31.
 */
public class PreheatListener implements SmartLifecycle {

    private static final Logger LOGGER = LoggerFactory.getLogger(PreheatListener.class);

    private static boolean isPreheat = false;

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public boolean isAutoStartup() {
        return true;
    }

    @Override
    public void stop(Runnable callback) {

    }

    @Override
    public void start() {
        synchronized (PreheatListener.class) {
            if (this.isPreheat) {
                return;
            }

            long start = System.currentTimeMillis();

            preheatFromSpiMechanism();

            preheatFromContainer();

            this.isPreheat = true;

            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug(">>> preheat cost time : " + (System.currentTimeMillis() - start) + " ms");
            }
        }
    }

    private void preheatFromSpiMechanism() {
        ServiceLoader<PreheatProvider> serviceLoader = ServiceLoader.load(PreheatProvider.class);
        Iterator<PreheatProvider> iterator = serviceLoader.iterator();
        while (iterator.hasNext()) {
            PreheatProvider preheatProvider = iterator.next();
            preheatProvider.doPreheat();
        }
    }

    private void preheatFromContainer() {
        Map<String, PreheatProvider> preheatProviders = applicationContext.getBeansOfType(PreheatProvider.class);
        if (preheatProviders != null && preheatProviders.size() > 0) {
            for (PreheatProvider preheatProvider : preheatProviders.values()) {
                preheatProvider.doPreheat();
            }
        }
    }

    @Override
    public void stop() {

    }

    @Override
    public boolean isRunning() {
        return false;
    }

    @Override
    public int getPhase() {
        return 0;// highest priority
    }

}
